Setup

n<-nrow(subset_selected)
set.seed(123)
n_s = sample(n,10000)
train = subset_selected[n_s, ]
crossValidationCont = function(df,K,a,nperfmeas=6)
{ set.seed(123)
  n = nrow(df)
  nhold = round(n/K) # size of holdout set 
  iperm = sample(n)
  perfmeas = matrix(0,K,nperfmeas)  
  models = vector(mode="list", length=3)
  year = vector(mode="list", length=3)
  for(k in 1:K)
  { indices = (((k-1)*nhold+1):(k*nhold))
    if( k==K ) indices = (((k-1)*nhold+1):n)
    indices = iperm[indices]
    traine = df[-indices,]
    holdoute = df[indices,]
    models[[k]] = lm(price~mark_cat+year+mileage_cat+log_vol_engine+fuel+car_type,data=traine)
    pred = predict(models[[k]],newdata=holdoute,interval="prediction",level=a)
    RSS = c(crossprod(models[[k]]$residuals))
    MSE = RSS / length(models[[k]]$residuals)
    x = intervalScore(pred, holdoute$price, a)
    y= sqrt(MSE)
    z = summary(models[[k]])$r.squared
    perfmeas[k,1:4] = x$summary
    perfmeas[k,5] = y
    perfmeas[k,6] = z
    year[[k]] = traine$year
  }
  avgperfmeas = apply(perfmeas,2,mean)
  list(perfmeasbyfold=perfmeas, avgperfmeas=avgperfmeas, models= models, year= year)
}
crossValidationCont2 = function(df,K,a,nperfmeas=6)
{ set.seed(123)
  n = nrow(df)
  nhold = round(n/K) # size of holdout set 
  iperm = sample(n)
  perfmeas = matrix(0,K,nperfmeas)  
  models = vector(mode="list", length=3)
  year = vector(mode="list", length=3)
  predi = vector(mode="list", length=3)
  pri = vector(mode="list", length=3)
  for(k in 1:K)
  { indices = (((k-1)*nhold+1):(k*nhold))
    if( k==K ) indices = (((k-1)*nhold+1):n)
    indices = iperm[indices]
    traine = df[-indices,]
    holdoute = df[indices,]
    models[[k]] = lm(price~mark_cat+year+mileage_cat+log_vol_engine+fuel+car_type,data=traine, weights = 1/(traine$year)^2)
    pred = predict(models[[k]],newdata=holdoute,interval="prediction",level=a, weights = 1/(holdoute$year)^2)
    RSS = c(crossprod(models[[k]]$residuals))
    MSE = RSS / length(models[[k]]$residuals)
    x = intervalScore(pred, holdoute$price, a)
    y= sqrt(MSE)
    z = summary(models[[k]])$r.squared
    perfmeas[k,1:4] = x$summary
    perfmeas[k,5] = y
    perfmeas[k,6] = z
    year[[k]] = traine$year
    predi[[k]] = pred
    pri[[k]] = holdoute$price
  }
  avgperfmeas = apply(perfmeas,2,mean)
  list(perfmeasbyfold=perfmeas, avgperfmeas=avgperfmeas, models= models, year= year, pred = predi, price = pri)
}
crossValidationCont3 = function(df,K,a,nperfmeas=6)
{ set.seed(123)
  n = nrow(df)
  nhold = round(n/K) # size of holdout set 
  iperm = sample(n)
  perfmeas = matrix(0,K,nperfmeas)  
  models = vector(mode="list", length=3)
  year = vector(mode="list", length=3)
  predi = vector(mode="list", length=3)
  pri = vector(mode="list", length=3)
  for(k in 1:K)
  { indices = (((k-1)*nhold+1):(k*nhold))
    if( k==K ) indices = (((k-1)*nhold+1):n)
    indices = iperm[indices]
    traine = df[-indices,]
    holdoute = df[indices,]
    models[[k]] = lm(I(log(price))~mark_cat+year+mileage_cat+log_vol_engine+fuel+car_type,data=traine)
    pred1 = predict(models[[k]],newdata=holdoute,interval="prediction",level=a)
    pred = exp(pred1)
    RSS = c(crossprod(models[[k]]$residuals))
    MSE = RSS / length(models[[k]]$residuals)
    x = intervalScore(pred, holdoute$price, a)
    y= sqrt(MSE)
    z = summary(models[[k]])$r.squared
    perfmeas[k,1:4] = x$summary
    perfmeas[k,5] = y
    perfmeas[k,6] = z
    year[[k]] = traine$year
    predi[[k]] = pred
    pri[[k]] = holdoute$price
  }
  avgperfmeas = apply(perfmeas,2,mean)
  list(perfmeasbyfold=perfmeas, avgperfmeas=avgperfmeas, models= models, year= year, pred = predi, price = pri)
}
intervalScore = function(predObj,actual,level) { 
n = nrow(predObj)
alpha = 1-level
ilow = (actual<predObj[,2]) # overestimation
ihigh = (actual>predObj[,3]) # underestimation
sumlength = sum(predObj[,3]-predObj[,2]) # sum of lengths of prediction intervals 
sumlow = sum(predObj[ilow,2]-actual[ilow])*2/alpha
sumhigh = sum(actual[ihigh]-predObj[ihigh,3])*2/alpha
avglength = sumlength/n
IS = (sumlength+sumlow+sumhigh)/n # average length + average under/over penalties 
cover = mean(actual>= predObj[,2] & actual<=predObj[,3])
summ = c(level,avglength,IS,cover)
# summary with level, average length, interval score, coverage rate, r^2, rmse
imiss = which(ilow | ihigh)
list(summary=summ, imiss=imiss)
}
ols_step_best_subset(lm(price~mark_cat+year+mileage_cat+log_vol_engine+fuel+car_type+gdpc,data=train))
                         Best Subsets Regression                          
--------------------------------------------------------------------------
Model Index    Predictors
--------------------------------------------------------------------------
     1         year                                                        
     2         year car_type                                               
     3         year mileage_cat car_type                                   
     4         year mileage_cat fuel car_type                              
     5         mark_cat year mileage_cat fuel car_type                     
     6         mark_cat year mileage_cat log_vol_engine fuel car_type      
     7         mark_cat year mileage_cat log_vol_engine fuel car_type gdpc 
--------------------------------------------------------------------------

                                                                  Subsets Regression Summary                                                                  
--------------------------------------------------------------------------------------------------------------------------------------------------------------
                       Adj.        Pred                                                                                                                        
Model    R-Square    R-Square    R-Square       C(p)           AIC           SBIC            SBC            MSEP             FPE             HSP         APC  
--------------------------------------------------------------------------------------------------------------------------------------------------------------
  1        0.4331      0.4330      0.4327    11826.1632    213461.9378    185080.4132    213483.5688    1.091154e+12    109137238.4019    10914.8160    0.5672 
  2        0.6354      0.6352      0.6348     4041.5913    209056.6401    180669.9789    209107.1124    701879354586.3881     70230066.4790     7023.7099    0.3649 
  3        0.7074      0.7071      0.7067     1268.9664    206864.1012    178470.4096    206950.6253    563184727342.0479     56380481.1251     5638.6131    0.2928 
  4        0.7245      0.7241      0.7235      614.7308    206269.6787    177872.3313    206377.8338    530418063646.8668     53116154.1273     5312.1482    0.2758 
  5        0.7337      0.7333      0.7327      261.4335    205934.9011    177533.8372    206064.6872    512698419504.8883     51357128.5591     5136.2286    0.2666 
  6        0.7407      0.7402      0.7393       -3.6592    205672.8528    177272.1069    205809.8493    499387849825.0785     50028809.8706     5003.3841    0.2597 
  7        0.7407      0.7402      0.7393       -3.0000    205673.5096    177272.7693    205817.7164    499370749041.4341     50032100.9365     5003.7141    0.2597 
--------------------------------------------------------------------------------------------------------------------------------------------------------------
AIC: Akaike Information Criteria 
 SBIC: Sawa's Bayesian Information Criteria 
 SBC: Schwarz Bayesian Criteria 
 MSEP: Estimated error of prediction, assuming multivariate normality 
 FPE: Final Prediction Error 
 HSP: Hocking's Sp 
 APC: Amemiya Prediction Criteria 
reg_model= crossValidationCont(train,3,0.5,6)
weighted_model = crossValidationCont2(train,3,0.5,6)
transformed_model = crossValidationCont3(train,3,0.8,6)
d = lm(price~mark_cat+year+mileage_cat+log_vol_engine+fuel+car_type,data=train)
plot(d$fitted.values,d$residuals, ylab="Residuals", xlab = "Fitted Values", main = "OLS Residuals")

plot(train$year,d$residuals, ylab="Residuals", xlab = "Year",main = "Year against OLS Residuals")

de = lm(price~mark_cat+year+mileage_cat+log_vol_engine+fuel+car_type,data=train, weights = 1/(train$year)^2)
plot(de$fitted.values,de$residuals, ylab="Residuals", xlab = "Fitted Values",main = "WLS Residuals")

plot(reg_model$models[[1]]$fitted.values,reg_model$models[[1]]$residuals)

plot(reg_model$models[[2]]$fitted.values,reg_model$models[[2]]$residuals)

plot(reg_model$models[[3]]$fitted.values,reg_model$models[[3]]$residuals)

plot(reg_model$year[[1]],reg_model$models[[1]]$residuals)

plot(reg_model$year[[2]],reg_model$models[[2]]$residuals)

plot(reg_model$year[[3]],reg_model$models[[3]]$residuals)

plot(weighted_model$models[[1]]$fitted.values,weighted_model$models[[1]]$residuals)

plot(weighted_model$models[[2]]$fitted.values,weighted_model$models[[2]]$residuals)

plot(weighted_model$models[[3]]$fitted.values,weighted_model$models[[3]]$residuals)

plot(transformed_model$models[[1]]$fitted.values,transformed_model$models[[1]]$residuals, main = "Fold 1", xlab = "Fitted Values", ylab = "Residuals")

plot(transformed_model$models[[2]]$fitted.values,transformed_model$models[[2]]$residuals, main = "Fold 2", xlab = "Fitted Values", ylab = "Residuals")

plot(transformed_model$models[[3]]$fitted.values,transformed_model$models[[3]]$residuals, main = "Fold 3", xlab = "Fitted Values", ylab = "Residuals")

res1 = transformed_model$price[[1]]  - exp(transformed_model$models[[1]]$fitted.values)
longer object length is not a multiple of shorter object length
res2 = transformed_model$price[[2]]  - exp(transformed_model$models[[2]]$fitted.values)
longer object length is not a multiple of shorter object length
res3 = transformed_model$price[[3]]  - exp(transformed_model$models[[3]]$fitted.values)
longer object length is not a multiple of shorter object length
plot(exp(transformed_model$models[[1]]$fitted.values),res1, main = "Fold 1", xlab = "Fitted Values", ylab = "Residuals")

plot(exp(transformed_model$models[[2]]$fitted.values),res2, main = "Fold 2", xlab = "Fitted Values", ylab = "Residuals")

plot(exp(transformed_model$models[[3]]$fitted.values),res3, main = "Fold 3", xlab = "Fitted Values", ylab = "Residuals")

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQojIFNldHVwCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmxpYnJhcnkobWxiZW5jaCkKbGlicmFyeShyYW5kb21Gb3Jlc3QpCmxpYnJhcnkocGFydHkpCmxpYnJhcnkocnBhcnQpCmxpYnJhcnkocnBhcnQucGxvdCkKbGlicmFyeShsZWFwcykKbGlicmFyeShvbHNycikKbGlicmFyeShtYWdyaXR0cikKbGlicmFyeSh0aWJibGUpCmBgYAoKYGBge3J9Cm48LW5yb3coc3Vic2V0X3NlbGVjdGVkKQpzZXQuc2VlZCgxMjMpCm5fcyA9IHNhbXBsZShuLDEwMDAwKQp0cmFpbiA9IHN1YnNldF9zZWxlY3RlZFtuX3MsIF0KYGBgCgoKYGBge3J9CmNyb3NzVmFsaWRhdGlvbkNvbnQgPSBmdW5jdGlvbihkZixLLGEsbnBlcmZtZWFzPTYpCnsgc2V0LnNlZWQoMTIzKQogIG4gPSBucm93KGRmKQogIG5ob2xkID0gcm91bmQobi9LKSAjIHNpemUgb2YgaG9sZG91dCBzZXQgCiAgaXBlcm0gPSBzYW1wbGUobikKICBwZXJmbWVhcyA9IG1hdHJpeCgwLEssbnBlcmZtZWFzKSAgCiAgbW9kZWxzID0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9MykKICB5ZWFyID0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9MykKICBmb3IoayBpbiAxOkspCiAgeyBpbmRpY2VzID0gKCgoay0xKSpuaG9sZCsxKTooaypuaG9sZCkpCiAgICBpZiggaz09SyApIGluZGljZXMgPSAoKChrLTEpKm5ob2xkKzEpOm4pCiAgICBpbmRpY2VzID0gaXBlcm1baW5kaWNlc10KICAgIHRyYWluZSA9IGRmWy1pbmRpY2VzLF0KICAgIGhvbGRvdXRlID0gZGZbaW5kaWNlcyxdCiAgICBtb2RlbHNbW2tdXSA9IGxtKHByaWNlfm1hcmtfY2F0K3llYXIrbWlsZWFnZV9jYXQrbG9nX3ZvbF9lbmdpbmUrZnVlbCtjYXJfdHlwZSxkYXRhPXRyYWluZSkKICAgIHByZWQgPSBwcmVkaWN0KG1vZGVsc1tba11dLG5ld2RhdGE9aG9sZG91dGUsaW50ZXJ2YWw9InByZWRpY3Rpb24iLGxldmVsPWEpCiAgICBSU1MgPSBjKGNyb3NzcHJvZChtb2RlbHNbW2tdXSRyZXNpZHVhbHMpKQogICAgTVNFID0gUlNTIC8gbGVuZ3RoKG1vZGVsc1tba11dJHJlc2lkdWFscykKICAgIHggPSBpbnRlcnZhbFNjb3JlKHByZWQsIGhvbGRvdXRlJHByaWNlLCBhKQogICAgeT0gc3FydChNU0UpCiAgICB6ID0gc3VtbWFyeShtb2RlbHNbW2tdXSkkci5zcXVhcmVkCiAgICBwZXJmbWVhc1trLDE6NF0gPSB4JHN1bW1hcnkKICAgIHBlcmZtZWFzW2ssNV0gPSB5CiAgICBwZXJmbWVhc1trLDZdID0gegogICAgeWVhcltba11dID0gdHJhaW5lJHllYXIKICB9CiAgYXZncGVyZm1lYXMgPSBhcHBseShwZXJmbWVhcywyLG1lYW4pCiAgbGlzdChwZXJmbWVhc2J5Zm9sZD1wZXJmbWVhcywgYXZncGVyZm1lYXM9YXZncGVyZm1lYXMsIG1vZGVscz0gbW9kZWxzLCB5ZWFyPSB5ZWFyKQp9CmBgYAoKYGBge3J9CmNyb3NzVmFsaWRhdGlvbkNvbnQyID0gZnVuY3Rpb24oZGYsSyxhLG5wZXJmbWVhcz02KQp7IHNldC5zZWVkKDEyMykKICBuID0gbnJvdyhkZikKICBuaG9sZCA9IHJvdW5kKG4vSykgIyBzaXplIG9mIGhvbGRvdXQgc2V0IAogIGlwZXJtID0gc2FtcGxlKG4pCiAgcGVyZm1lYXMgPSBtYXRyaXgoMCxLLG5wZXJmbWVhcykgIAogIG1vZGVscyA9IHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPTMpCiAgeWVhciA9IHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPTMpCiAgcHJlZGkgPSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD0zKQogIHByaSA9IHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPTMpCiAgZm9yKGsgaW4gMTpLKQogIHsgaW5kaWNlcyA9ICgoKGstMSkqbmhvbGQrMSk6KGsqbmhvbGQpKQogICAgaWYoIGs9PUsgKSBpbmRpY2VzID0gKCgoay0xKSpuaG9sZCsxKTpuKQogICAgaW5kaWNlcyA9IGlwZXJtW2luZGljZXNdCiAgICB0cmFpbmUgPSBkZlstaW5kaWNlcyxdCiAgICBob2xkb3V0ZSA9IGRmW2luZGljZXMsXQogICAgbW9kZWxzW1trXV0gPSBsbShwcmljZX5tYXJrX2NhdCt5ZWFyK21pbGVhZ2VfY2F0K2xvZ192b2xfZW5naW5lK2Z1ZWwrY2FyX3R5cGUsZGF0YT10cmFpbmUsIHdlaWdodHMgPSAxLyh0cmFpbmUkeWVhcileMikKICAgIHByZWQgPSBwcmVkaWN0KG1vZGVsc1tba11dLG5ld2RhdGE9aG9sZG91dGUsaW50ZXJ2YWw9InByZWRpY3Rpb24iLGxldmVsPWEsIHdlaWdodHMgPSAxLyhob2xkb3V0ZSR5ZWFyKV4yKQogICAgUlNTID0gYyhjcm9zc3Byb2QobW9kZWxzW1trXV0kcmVzaWR1YWxzKSkKICAgIE1TRSA9IFJTUyAvIGxlbmd0aChtb2RlbHNbW2tdXSRyZXNpZHVhbHMpCiAgICB4ID0gaW50ZXJ2YWxTY29yZShwcmVkLCBob2xkb3V0ZSRwcmljZSwgYSkKICAgIHk9IHNxcnQoTVNFKQogICAgeiA9IHN1bW1hcnkobW9kZWxzW1trXV0pJHIuc3F1YXJlZAogICAgcGVyZm1lYXNbaywxOjRdID0geCRzdW1tYXJ5CiAgICBwZXJmbWVhc1trLDVdID0geQogICAgcGVyZm1lYXNbayw2XSA9IHoKICAgIHllYXJbW2tdXSA9IHRyYWluZSR5ZWFyCiAgICBwcmVkaVtba11dID0gcHJlZAogICAgcHJpW1trXV0gPSBob2xkb3V0ZSRwcmljZQogIH0KICBhdmdwZXJmbWVhcyA9IGFwcGx5KHBlcmZtZWFzLDIsbWVhbikKICBsaXN0KHBlcmZtZWFzYnlmb2xkPXBlcmZtZWFzLCBhdmdwZXJmbWVhcz1hdmdwZXJmbWVhcywgbW9kZWxzPSBtb2RlbHMsIHllYXI9IHllYXIsIHByZWQgPSBwcmVkaSwgcHJpY2UgPSBwcmkpCn0KYGBgCgpgYGB7cn0KY3Jvc3NWYWxpZGF0aW9uQ29udDMgPSBmdW5jdGlvbihkZixLLGEsbnBlcmZtZWFzPTYpCnsgc2V0LnNlZWQoMTIzKQogIG4gPSBucm93KGRmKQogIG5ob2xkID0gcm91bmQobi9LKSAjIHNpemUgb2YgaG9sZG91dCBzZXQgCiAgaXBlcm0gPSBzYW1wbGUobikKICBwZXJmbWVhcyA9IG1hdHJpeCgwLEssbnBlcmZtZWFzKSAgCiAgbW9kZWxzID0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9MykKICB5ZWFyID0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9MykKICBwcmVkaSA9IHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPTMpCiAgcHJpID0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9MykKICBmb3IoayBpbiAxOkspCiAgeyBpbmRpY2VzID0gKCgoay0xKSpuaG9sZCsxKTooaypuaG9sZCkpCiAgICBpZiggaz09SyApIGluZGljZXMgPSAoKChrLTEpKm5ob2xkKzEpOm4pCiAgICBpbmRpY2VzID0gaXBlcm1baW5kaWNlc10KICAgIHRyYWluZSA9IGRmWy1pbmRpY2VzLF0KICAgIGhvbGRvdXRlID0gZGZbaW5kaWNlcyxdCiAgICBtb2RlbHNbW2tdXSA9IGxtKEkobG9nKHByaWNlKSl+bWFya19jYXQreWVhcittaWxlYWdlX2NhdCtsb2dfdm9sX2VuZ2luZStmdWVsK2Nhcl90eXBlLGRhdGE9dHJhaW5lKQogICAgcHJlZDEgPSBwcmVkaWN0KG1vZGVsc1tba11dLG5ld2RhdGE9aG9sZG91dGUsaW50ZXJ2YWw9InByZWRpY3Rpb24iLGxldmVsPWEpCiAgICBwcmVkID0gZXhwKHByZWQxKQogICAgUlNTID0gYyhjcm9zc3Byb2QobW9kZWxzW1trXV0kcmVzaWR1YWxzKSkKICAgIE1TRSA9IFJTUyAvIGxlbmd0aChtb2RlbHNbW2tdXSRyZXNpZHVhbHMpCiAgICB4ID0gaW50ZXJ2YWxTY29yZShwcmVkLCBob2xkb3V0ZSRwcmljZSwgYSkKICAgIHk9IHNxcnQoTVNFKQogICAgeiA9IHN1bW1hcnkobW9kZWxzW1trXV0pJHIuc3F1YXJlZAogICAgcGVyZm1lYXNbaywxOjRdID0geCRzdW1tYXJ5CiAgICBwZXJmbWVhc1trLDVdID0geQogICAgcGVyZm1lYXNbayw2XSA9IHoKICAgIHllYXJbW2tdXSA9IHRyYWluZSR5ZWFyCiAgICBwcmVkaVtba11dID0gcHJlZAogICAgcHJpW1trXV0gPSBob2xkb3V0ZSRwcmljZQogIH0KICBhdmdwZXJmbWVhcyA9IGFwcGx5KHBlcmZtZWFzLDIsbWVhbikKICBsaXN0KHBlcmZtZWFzYnlmb2xkPXBlcmZtZWFzLCBhdmdwZXJmbWVhcz1hdmdwZXJmbWVhcywgbW9kZWxzPSBtb2RlbHMsIHllYXI9IHllYXIsIHByZWQgPSBwcmVkaSwgcHJpY2UgPSBwcmkpCn0KYGBgCgpgYGB7cn0KaW50ZXJ2YWxTY29yZSA9IGZ1bmN0aW9uKHByZWRPYmosYWN0dWFsLGxldmVsKSB7IApuID0gbnJvdyhwcmVkT2JqKQphbHBoYSA9IDEtbGV2ZWwKaWxvdyA9IChhY3R1YWw8cHJlZE9ialssMl0pICMgb3ZlcmVzdGltYXRpb24KaWhpZ2ggPSAoYWN0dWFsPnByZWRPYmpbLDNdKSAjIHVuZGVyZXN0aW1hdGlvbgpzdW1sZW5ndGggPSBzdW0ocHJlZE9ialssM10tcHJlZE9ialssMl0pICMgc3VtIG9mIGxlbmd0aHMgb2YgcHJlZGljdGlvbiBpbnRlcnZhbHMgCnN1bWxvdyA9IHN1bShwcmVkT2JqW2lsb3csMl0tYWN0dWFsW2lsb3ddKSoyL2FscGhhCnN1bWhpZ2ggPSBzdW0oYWN0dWFsW2loaWdoXS1wcmVkT2JqW2loaWdoLDNdKSoyL2FscGhhCmF2Z2xlbmd0aCA9IHN1bWxlbmd0aC9uCklTID0gKHN1bWxlbmd0aCtzdW1sb3crc3VtaGlnaCkvbiAjIGF2ZXJhZ2UgbGVuZ3RoICsgYXZlcmFnZSB1bmRlci9vdmVyIHBlbmFsdGllcyAKY292ZXIgPSBtZWFuKGFjdHVhbD49IHByZWRPYmpbLDJdICYgYWN0dWFsPD1wcmVkT2JqWywzXSkKc3VtbSA9IGMobGV2ZWwsYXZnbGVuZ3RoLElTLGNvdmVyKQojIHN1bW1hcnkgd2l0aCBsZXZlbCwgYXZlcmFnZSBsZW5ndGgsIGludGVydmFsIHNjb3JlLCBjb3ZlcmFnZSByYXRlLCByXjIsIHJtc2UKaW1pc3MgPSB3aGljaChpbG93IHwgaWhpZ2gpCmxpc3Qoc3VtbWFyeT1zdW1tLCBpbWlzcz1pbWlzcykKfQpvbHNfc3RlcF9iZXN0X3N1YnNldChsbShwcmljZX5tYXJrX2NhdCt5ZWFyK21pbGVhZ2VfY2F0K2xvZ192b2xfZW5naW5lK2Z1ZWwrY2FyX3R5cGUrZ2RwYyxkYXRhPXRyYWluKSkKcmVnX21vZGVsPSBjcm9zc1ZhbGlkYXRpb25Db250KHRyYWluLDMsMC41LDYpCndlaWdodGVkX21vZGVsID0gY3Jvc3NWYWxpZGF0aW9uQ29udDIodHJhaW4sMywwLjUsNikKdHJhbnNmb3JtZWRfbW9kZWwgPSBjcm9zc1ZhbGlkYXRpb25Db250Myh0cmFpbiwzLDAuOCw2KQpgYGAKCmBgYHtyfQpkID0gbG0ocHJpY2V+bWFya19jYXQreWVhcittaWxlYWdlX2NhdCtsb2dfdm9sX2VuZ2luZStmdWVsK2Nhcl90eXBlLGRhdGE9dHJhaW4pCnBsb3QoZCRmaXR0ZWQudmFsdWVzLGQkcmVzaWR1YWxzLCB5bGFiPSJSZXNpZHVhbHMiLCB4bGFiID0gIkZpdHRlZCBWYWx1ZXMiLCBtYWluID0gIk9MUyBSZXNpZHVhbHMiKQpwbG90KHRyYWluJHllYXIsZCRyZXNpZHVhbHMsIHlsYWI9IlJlc2lkdWFscyIsIHhsYWIgPSAiWWVhciIsbWFpbiA9ICJZZWFyIGFnYWluc3QgT0xTIFJlc2lkdWFscyIpCmRlID0gbG0ocHJpY2V+bWFya19jYXQreWVhcittaWxlYWdlX2NhdCtsb2dfdm9sX2VuZ2luZStmdWVsK2Nhcl90eXBlLGRhdGE9dHJhaW4sIHdlaWdodHMgPSAxLyh0cmFpbiR5ZWFyKV4yKQpwbG90KGRlJGZpdHRlZC52YWx1ZXMsZGUkcmVzaWR1YWxzLCB5bGFiPSJSZXNpZHVhbHMiLCB4bGFiID0gIkZpdHRlZCBWYWx1ZXMiLG1haW4gPSAiV0xTIFJlc2lkdWFscyIpCmBgYAoKCmBgYHtyfQpwbG90KHJlZ19tb2RlbCRtb2RlbHNbWzFdXSRmaXR0ZWQudmFsdWVzLHJlZ19tb2RlbCRtb2RlbHNbWzFdXSRyZXNpZHVhbHMpCnBsb3QocmVnX21vZGVsJG1vZGVsc1tbMl1dJGZpdHRlZC52YWx1ZXMscmVnX21vZGVsJG1vZGVsc1tbMl1dJHJlc2lkdWFscykKcGxvdChyZWdfbW9kZWwkbW9kZWxzW1szXV0kZml0dGVkLnZhbHVlcyxyZWdfbW9kZWwkbW9kZWxzW1szXV0kcmVzaWR1YWxzKQpgYGAKCmBgYHtyfQpwbG90KHJlZ19tb2RlbCR5ZWFyW1sxXV0scmVnX21vZGVsJG1vZGVsc1tbMV1dJHJlc2lkdWFscykKcGxvdChyZWdfbW9kZWwkeWVhcltbMl1dLHJlZ19tb2RlbCRtb2RlbHNbWzJdXSRyZXNpZHVhbHMpCnBsb3QocmVnX21vZGVsJHllYXJbWzNdXSxyZWdfbW9kZWwkbW9kZWxzW1szXV0kcmVzaWR1YWxzKQpgYGAKCmBgYHtyfQpwbG90KHdlaWdodGVkX21vZGVsJG1vZGVsc1tbMV1dJGZpdHRlZC52YWx1ZXMsd2VpZ2h0ZWRfbW9kZWwkbW9kZWxzW1sxXV0kcmVzaWR1YWxzKQpwbG90KHdlaWdodGVkX21vZGVsJG1vZGVsc1tbMl1dJGZpdHRlZC52YWx1ZXMsd2VpZ2h0ZWRfbW9kZWwkbW9kZWxzW1syXV0kcmVzaWR1YWxzKQpwbG90KHdlaWdodGVkX21vZGVsJG1vZGVsc1tbM11dJGZpdHRlZC52YWx1ZXMsd2VpZ2h0ZWRfbW9kZWwkbW9kZWxzW1szXV0kcmVzaWR1YWxzKQpgYGAKYGBge3J9CnBsb3QodHJhbnNmb3JtZWRfbW9kZWwkbW9kZWxzW1sxXV0kZml0dGVkLnZhbHVlcyx0cmFuc2Zvcm1lZF9tb2RlbCRtb2RlbHNbWzFdXSRyZXNpZHVhbHMsIG1haW4gPSAiRm9sZCAxIiwgeGxhYiA9ICJGaXR0ZWQgVmFsdWVzIiwgeWxhYiA9ICJSZXNpZHVhbHMiKQpwbG90KHRyYW5zZm9ybWVkX21vZGVsJG1vZGVsc1tbMl1dJGZpdHRlZC52YWx1ZXMsdHJhbnNmb3JtZWRfbW9kZWwkbW9kZWxzW1syXV0kcmVzaWR1YWxzLCBtYWluID0gIkZvbGQgMiIsIHhsYWIgPSAiRml0dGVkIFZhbHVlcyIsIHlsYWIgPSAiUmVzaWR1YWxzIikKcGxvdCh0cmFuc2Zvcm1lZF9tb2RlbCRtb2RlbHNbWzNdXSRmaXR0ZWQudmFsdWVzLHRyYW5zZm9ybWVkX21vZGVsJG1vZGVsc1tbM11dJHJlc2lkdWFscywgbWFpbiA9ICJGb2xkIDMiLCB4bGFiID0gIkZpdHRlZCBWYWx1ZXMiLCB5bGFiID0gIlJlc2lkdWFscyIpCmBgYAoKYGBge3J9CnJlczEgPSB0cmFuc2Zvcm1lZF9tb2RlbCRwcmljZVtbMV1dICAtIGV4cCh0cmFuc2Zvcm1lZF9tb2RlbCRtb2RlbHNbWzFdXSRmaXR0ZWQudmFsdWVzKQpyZXMyID0gdHJhbnNmb3JtZWRfbW9kZWwkcHJpY2VbWzJdXSAgLSBleHAodHJhbnNmb3JtZWRfbW9kZWwkbW9kZWxzW1syXV0kZml0dGVkLnZhbHVlcykKcmVzMyA9IHRyYW5zZm9ybWVkX21vZGVsJHByaWNlW1szXV0gIC0gZXhwKHRyYW5zZm9ybWVkX21vZGVsJG1vZGVsc1tbM11dJGZpdHRlZC52YWx1ZXMpCnBsb3QoZXhwKHRyYW5zZm9ybWVkX21vZGVsJG1vZGVsc1tbMV1dJGZpdHRlZC52YWx1ZXMpLHJlczEsIG1haW4gPSAiRm9sZCAxIiwgeGxhYiA9ICJGaXR0ZWQgVmFsdWVzIiwgeWxhYiA9ICJSZXNpZHVhbHMiKQpwbG90KGV4cCh0cmFuc2Zvcm1lZF9tb2RlbCRtb2RlbHNbWzJdXSRmaXR0ZWQudmFsdWVzKSxyZXMyLCBtYWluID0gIkZvbGQgMiIsIHhsYWIgPSAiRml0dGVkIFZhbHVlcyIsIHlsYWIgPSAiUmVzaWR1YWxzIikKcGxvdChleHAodHJhbnNmb3JtZWRfbW9kZWwkbW9kZWxzW1szXV0kZml0dGVkLnZhbHVlcykscmVzMywgbWFpbiA9ICJGb2xkIDMiLCB4bGFiID0gIkZpdHRlZCBWYWx1ZXMiLCB5bGFiID0gIlJlc2lkdWFscyIpCmBgYA==